/**
 * 
 */
package com.miolr.core.query;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * @author iday
 *
 */
public class PageModel implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 2250626813378194728L;

	public static final int MAX_RECORD = 20;

	private Map<String, Object> params = new HashMap<String, Object>();
	
	private int totalPages = 0;
	private int page = 1;
	private int maxRecord = MAX_RECORD;
	private long totalRecords = 0;
	private int RECORD_LIMIT = 100;

	private int center = 9;
	private int edge = 2;

	/**
	 * 
	 */
	public PageModel() {
		super();
	}

	/**
	 * @param maxRecord
	 */
	public PageModel(int maxRecord) {
		super();
		this.maxRecord = maxRecord;
	}

	/**
	 * @param page
	 * @param maxRecord
	 */
	public PageModel(int page, int maxRecord) {
		super();
		this.page = page;
		this.maxRecord = maxRecord;
	}

	/**
	 * @param page
	 * @param maxRecord
	 * @param displayEntries
	 */
	public PageModel(int page, int maxRecord, int displayEntries) {
		super();
		this.page = page;
		this.maxRecord = maxRecord;
		this.center = displayEntries;
	}
	
	public Object getParam(String key) {
		Object obj = params.get(key);
		if (obj instanceof Parameter) {
			Parameter param = (Parameter) obj;
			return param.value();
		}
		return obj;
	}
	
	public Object getRawParam(String key) {
		return params.get(key);
	}
	
	public void setParam(String key, Object value) {
		params.put(key, value);
	}
	
	/**
	 * @return the params
	 */
	public Map<String, Object> getParams() {
		return params;
	}

	/**
	 * @param params the params to set
	 */
	public void setParams(Map<String, Object> params) {
		this.params = params;
	}

	/**
	 * @return the page
	 */
	public int getPage() {
		return page;
	}

	/**
	 * @return the maxRecord
	 */
	public int getMaxRecord() {
		return maxRecord;
	}

	/**
	 * @return the totalPages
	 */
	public int getTotalPages() {
		return totalPages;
	}

	public void genTotalPages() {
		if (this.totalRecords == 0) {
			this.totalPages = 1;
		} else {
			this.totalPages = (int) Math.ceil((double) this.totalRecords
					/ this.maxRecord);
		}
	}

	/**
	 * @return the totalRecords
	 */
	public long getTotalRecords() {
		return totalRecords;
	}

	public int getFirstRecord() {
		return this.page <= 0 ? 0 : (this.page - 1) * this.maxRecord;
	}

	/**
	 * @param page
	 *            the page to set
	 */
	public void setPage(int currentPage) {
		this.page = currentPage;
	}

	/**
	 * @param maxRecord
	 *            the maxRecord to set
	 */
	public void setMaxRecord(int maxRecord) {
		this.maxRecord = (maxRecord > RECORD_LIMIT) ? RECORD_LIMIT : maxRecord;
	}

	/**
	 * @param totalPages
	 *            the totalPages to set
	 */
	public void setTotalPages(int totalPages) {
		this.totalPages = totalPages;
	}

	/**
	 * @param totalRecords
	 *            the totalRecords to set
	 */
	public void setTotalRecords(long totalRecords) {
		this.totalRecords = totalRecords;
		genTotalPages();
	}

	/**
	 * @return the center
	 */
	public int getCenter() {
		return center;
	}

	/**
	 * @param center
	 *            the center to set
	 */
	public void setCenter(int center) {
		this.center = center;
	}

	/**
	 * @return the edge
	 */
	public int getEdge() {
		return edge;
	}

	/**
	 * @param edge
	 *            the edge to set
	 */
	public void setEdge(int edge) {
		this.edge = edge;
	}

	public boolean isFirstPage() {
		return this.page == 1;
	}

	public boolean isLastPage() {
		return this.page == this.getTotalPages();
	}

	public int getCenterFirst() {
		if (this.getTotalPages() <= center) {
			return 1;
		}
		if (page > this.getTotalPages() - center + 1) {
			return this.getTotalPages() - center + 1;
		}
		int h = center / 2;
		if (page >= center) {
			return page - h;
		}
		return 1;
	}

	public int getCenterLast() {
		if (this.getTotalPages() <= center) {
			return this.getTotalPages();
		}
		if (page < center) {
			return center;
		}
		int h = center / 2;
		if (page <= this.getTotalPages() - center + 1) {
			return page + h;
		} else {
			return this.getTotalPages();
		}
	}

	public int getEdgeFirst() {
		return edge > this.getTotalPages() ? this.getTotalPages() : edge;
	}

	public int getEdgeLast() {
		return this.getTotalPages() - edge + 1;
	}

	public int getPageNext() {
		return this.page + 1;
	}

	public int getPageLast() {
		return this.page - 1;
	}
}
